#页面父类
#主要放：每个web页面都需要的一些通用的UI操作/方法、通用的属性
import time,os,sys

from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains

class PageBase(object):
    def __init__(self,driver,base_url):
        self.driver=driver
        self.base_url=base_url

    #打开某网址url
    def open(self,url):#"/webzdh/form.html"
        self.driver.get(self.base_url+url)

    #根据元素的定位特征loc来定位元素
    def find_element(self,loc):
        by=loc[0]
        value=loc[1]
        return self.driver.find_element(by,value)

    #控件：文本框、密码框、多行文本框
    #给元素loc输入数据data
    def input(self,loc,data):
        self.find_element(loc).send_keys(data)

    #控件：文本框、密码框、多行文本框
    #清空(失去焦点)
    def clear1(self,loc):
        self.find_element(loc).clear()

    #控件：文本框、密码框、多行文本框
    #清空（不会失去焦点）
    def clear2(self,loc):
        ele=self.find_element(loc)
        ele.send_keys(Keys.CONTROL,"a")
        ele.send_keys(Keys.BACK_SPACE)

    #获取元素loc的文本内容
    def getEleText(self,loc):
        return self.find_element(loc).text.strip()

    #获取元素loc的属性attr的值
    def getEleAttr(self,loc,attrName):
        return self.find_element(loc).get_attribute(attrName).strip()

    #控件：文本框 、密码框、多行文本框
    #获取用户输入的数据
    def getUserData1(self,loc):
        return self.getEleAttr(loc,"value")

    #控件：单选按钮
    #选中某选项
    def selectRadio(self,attrName,optionValue):
        #<input type="radio" name="sex" value="M">
        self.driver.find_element(By.CSS_SELECTOR,f"input[type='radio'][name='{attrName}'][value='{optionValue}']").click()

    #控件：单选按钮
    #判断某选项是否是选中
    def isSelectedRadio(self,attrName,optionValue):
        return self.driver.find_element(By.CSS_SELECTOR, f"input[type='radio'][name='{attrName}'][value='{optionValue}']").is_selected()

    #控制：单选按钮
    #输出用户的那个选项的value属性的值
    def getUserData2(self,attrName):
        ret=""
        #<input type="radio" name="sex" value="M">男
        eles=self.driver.find_elements(By.CSS_SELECTOR,f"input[type='radio'][name='{attrName}'][value]")
        for x in eles:
            status=x.is_selected()
            if status:
                ret=x.get_attribute("value").strip()
                break
        return ret


    #控件：复选框
    #选中N个选项：0 1 2 3 4
    def selectCheckbox(self,attrName,targetValues):#"dalanqiu,tizuqiu" "" "dalanqiu"
        # <input type="checkbox" name="aihao" value="dalanqiu" d>打篮球
        eles=self.driver.find_elements(By.CSS_SELECTOR,f"input[type='checkbox'][name='{attrName}'][value]")
        for x in eles:
            attrValue=x.get_attribute("value").strip() #"dalanqiu" "tizuqiu" "wanyouxi"
            status = x.is_selected()
            if attrValue in targetValues:
                if not status:
                    x.click()
            else:
                if status:
                    x.click()

    #控制：复选框
    #功能：全选
    def selectAllCheckbox(self,attrName):#"dalanqiu,tizuqiu" "" "dalanqiu"
        # <input type="checkbox" name="aihao" value="dalanqiu" d>打篮球
        eles=self.driver.find_elements(By.CSS_SELECTOR,f"input[type='checkbox'][name='{attrName}'][value]")
        for x in eles:
            status = x.is_selected()
            if not status:
                x.click()

    # 控制：复选框
    # 功能：反选
    def selectNotCheckbox(self, attrName ):  # "dalanqiu,tizuqiu" "" "dalanqiu"
        # <input type="checkbox" name="aihao" value="dalanqiu" d>打篮球
        eles = self.driver.find_elements(By.CSS_SELECTOR, f"input[type='checkbox'][name='{attrName}'][value]")
        for x in eles:
            x.click()

    # 控制：复选框
    # 功能：全不选
    def selectDisAllCheckbox(self, attrName):  # "dalanqiu,tizuqiu" "" "dalanqiu"
        # <input type="checkbox" name="aihao" value="dalanqiu" d>打篮球
        eles = self.driver.find_elements(By.CSS_SELECTOR, f"input[type='checkbox'][name='{attrName}'][value]")
        for x in eles:
            status = x.is_selected()
            if status:
                x.click()

    #功能：复选框
    #判断某选项的选中状态
    def isSelectedCheckbox(self,attrName,optionValue):
        #input type="checkbox" name="aihao" value="dalanqiu" d>打篮球
        return self.driver.find_element(By.CSS_SELECTOR, f"input[type='checkbox'][name='{attrName}'][value='{optionValue}']").is_selected()

    # 控制：复选框
    # 功能：获取用户选中的那些选项的values
    def getUserData3(self, attrName):  # "dalanqiu,tizuqiu" "" "dalanqiu"
        # <input type="checkbox" name="aihao" value="dalanqiu" d>打篮球
        ret=""
        eles = self.driver.find_elements(By.CSS_SELECTOR, f"input[type='checkbox'][name='{attrName}'][value]")
        for x in eles:
            status=x.is_selected()
            if status:
                attrValue=x.get_attribute("value").strip() #"dalanqiu" "tizuqiu"
                ret+=attrValue+","
        return ret[:-1]

    #控制：下拉列表
    #根据选项的下标来选中某选项
    def selectSelectByIndex(self,attrSelectName,optionIndex):#从0
        #<select name="degree">
        ele_select=self.driver.find_element(By.CSS_SELECTOR,f"select[name='{attrSelectName}']")
        ss=Select(ele_select)
        ss.select_by_index(optionIndex)

    # 控制：下拉列表
    # 根据选项的value属性来选中某选项
    def selectSelectByIndex(self, attrSelectName, optionValue):  # 从0
        # <select name="degree">
        ele_select = self.driver.find_element(By.CSS_SELECTOR, f"select[name='{attrSelectName}']")
        ss = Select(ele_select)
        ss.select_by_value(optionValue)

    # 控制：下拉列表
    # 根据选项的文本内容属性来选中某选项
    def selectSelectByText(self, attrSelectName, optionText):
        # <select name="degree">
        ele_select = self.driver.find_element(By.CSS_SELECTOR, f"select[name='{attrSelectName}']")
        ss = Select(ele_select)
        ss.select_by_visible_text(optionText)

    #控件：下拉列表
    #判断某选项是否选中
    def isSelectedSelect(self,attrSelectName,targetOptionText):
        ele_select = self.driver.find_element(By.CSS_SELECTOR, f"select[name='{attrSelectName}']")
        ss = Select(ele_select)
        selected_option=ss.first_selected_option
        selectText=selected_option.text
        return selectText==targetOptionText

    # 控件：下拉列表
    # 输出用户选中的那个选项的文本内容
    def getUserData4(self, attrSelectName):
        ele_select = self.driver.find_element(By.CSS_SELECTOR, f"select[name='{attrSelectName}']")
        ss = Select(ele_select)
        selected_option = ss.first_selected_option
        return selected_option.text

    #判断某元素loc是否有某属性attrName
    def isExistsEleAttr(self,loc,attrName):
        ele=self.find_element(loc)
        return ele.get_attribute(attrName) is not None

    #删除某元素loc的某属性
    def removeEleAttr(self,loc,attrName):
        ele=self.find_element(loc)
        self.driver.execute_script("arguments[0].removeAttribute(arguments[0])", ele, attrName)

    #控件：日期
    #输入某日期值
    def inputRiqi(self,loc,riqi):
        ele =self.find_element(loc)
        if self.isExistsEleAttr(loc,"readonly"):
            self.removeEleAttr(loc,"readonly")
        self.driver.execute_script("arguments[0].value=arguments[1]", ele, riqi)

    #控制：日期
    #获取用户输入的日期值
    def getUserData5(self,loc):
        return self.getEleAttr(loc,"value")


    #控件：按钮类控件(click)
    #点击某元素
    def click(self,loc):
        self.find_element(loc).click()

    # 控件：按钮类控件(鼠标点击)
    # 点击某元素
    def click_mouse(self,loc):
        ele=self.find_element(loc)
        ActionChains(self.driver).click(ele).perform()

    #控件：文件框/文件上传
    #用输入的方式来上传文件。数量：任意。0个 1个 N个 不通用
    def uploadFile1(self,loc,filePaths):#"C:/A/1.png,C:/A/2.png,C:/A/3.png"
        if filePaths=="" or filePaths==None:
            pass
        else:
            ele=self.find_element(loc)
            filePaths=filePaths.replace(",","\n")
            ele.send_keys(filePaths)


    #控件:文件框/文件上传
    #用autoIT方式来上传文件。数量：任意：0个、1个 N个。通用
    def uploadFile2(self,loc,filePaths):#"C:/A/1.png.C:/A/2.jpg"
        if filePaths==None or filePaths=="":
            pass
        else:
            #完成步骤1
            self.click_mouse(loc)
            time.sleep(2)

            b = filePaths.split(",")  # ["C:/A/1.png","C:/A/2.png"]
            ret = ""
            for x in b:  # C:/A/1.png C:/A/2.png
                ret += '"' + x + '" '

            ret = ret.replace("/", "\\")

            #完成步骤2和步骤3：uploadFile.exe
            os.system(f'C:/B/uploadFile.exe {ret}')


    #保存当前网页截图
    def savePng(self,serviceName,key):
        imgName=f"{serviceName}_{key}_{time.strftime('%Y%m%d%H%M%S')}"
        self.driver.get_screenshot_as_file(f"./screen/{imgName}.png")
        return imgName #"登录_K001_20241224164601"




